{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to atomman: Defining atomic systems\n",
    "\n",
    "__Lucas M. Hale__, [lucas.hale@nist.gov](mailto:lucas.hale@nist.gov?Subject=ipr-demo), _Materials Science and Engineering Division, NIST_.\n",
    "    \n",
    "[Disclaimers](http://www.nist.gov/public_affairs/disclaimer.cfm) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Introduction <a id='section1'></a>\n",
    "\n",
    "This Notebook provides an introduction to creating and manipulating atomistic systems using atomman. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Library Imports**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "atomman version = 1.4.0\n",
      "Notebook executed on 2021-08-03\n"
     ]
    }
   ],
   "source": [
    "# Standard Python libraries\n",
    "import os\n",
    "from copy import deepcopy\n",
    "import datetime\n",
    "\n",
    "# http://www.numpy.org/\n",
    "import numpy as np    \n",
    "\n",
    "# https://github.com/usnistgov/atomman\n",
    "import atomman as am        \n",
    "import atomman.unitconvert as uc\n",
    "\n",
    "# Show atomman version\n",
    "print('atomman version =', am.__version__)\n",
    "\n",
    "# Show date of Notebook execution\n",
    "print('Notebook executed on', datetime.date.today())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Create a System <a id='section2'></a>\n",
    "\n",
    "Atomic systems are represented with three Python objects: Box, Atoms, and System."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1. Box\n",
    "\n",
    "The Box class defines a generic parallelepiped for the system's boundaries.  \n",
    "\n",
    "See the [1.1. Box class Jupyter Notebook](1.1._Box_class.html) for more detailed information and options."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.1.1. Create Box\n",
    "\n",
    "Boxes can be defined using a variety of formats.  Here, we'll define a box using lattice parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# a = 4.05 angstroms (Al fcc lattice constant)\n",
    "a = uc.set_in_units(4.05, 'angstrom')\n",
    "\n",
    "# Create cubic box\n",
    "box = am.Box.cubic(a=a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.1.2. Access Box properties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The string of Box shows four Cartesian vectors: the three box vectors (avect, bvect, and cvect) and the origin position."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 4.050,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  4.050,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n"
     ]
    }
   ],
   "source": [
    "print(box)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The parameters of the Box can also be retrieved in a variety of formats.  Some examples are shown here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a = 4.05\n",
      "b = 4.05\n",
      "c = 4.05\n",
      "alpha = 90.0\n",
      "beta  = 90.0\n",
      "gamma = 90.0\n"
     ]
    }
   ],
   "source": [
    "print('a =', box.a)\n",
    "print('b =', box.b)\n",
    "print('c =', box.c)\n",
    "print('alpha =', box.alpha)\n",
    "print('beta  =', box.beta)\n",
    "print('gamma =', box.gamma)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2. Atoms\n",
    "\n",
    "The Atoms class collects per-atom properties that can be freely assigned. The only limitations are that the number of atoms is constant, and that values for the per-atom properties must be given for all atoms.\n",
    "\n",
    "See the [1.2. Atoms class Jupyter Notebook](1.2._Atoms_class.html) for more detailed information and options."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.1. Create Atoms\n",
    "\n",
    "When initializing an Atoms object, all keyword arguments (except natoms and prop) will be interpreted as property names.  Values for each property must be given for each atom, or only one value given in which case all atoms will be assigned the same value.\n",
    "\n",
    "By default, each Atoms instance has two per-atom properties: \n",
    "\n",
    "- __atype__ is an integer atomic type. If not given, atype will be set to 1 for all atoms.\n",
    "\n",
    "- __pos__ is the 3D vector position.  If not given, pos will be set to [0,0,0] for all atoms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Atoms for an fcc unit cell\n",
    "atype = 1\n",
    "pos = [[0.0, 0.0, 0.0], \n",
    "       [0.5, 0.5, 0.0], \n",
    "       [0.5, 0.0, 0.5], \n",
    "       [0.0, 0.5, 0.5]]\n",
    "\n",
    "atoms = am.Atoms(atype=atype, pos=pos)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.2. Accessing Atoms properties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The string of Atoms shows id, atype, and pos for all atoms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   0.000 |   0.000 |   0.000\n",
      "      1 |       1 |   0.500 |   0.500 |   0.000\n",
      "      2 |       1 |   0.500 |   0.000 |   0.500\n",
      "      3 |       1 |   0.000 |   0.500 |   0.500\n"
     ]
    }
   ],
   "source": [
    "print(atoms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The per-atom properties can be accessed as attributes of the object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "atoms.atype -> [1 1 1 1]\n",
      "atoms.pos[2] -> [0.5 0.  0.5]\n"
     ]
    }
   ],
   "source": [
    "print('atoms.atype ->', atoms.atype)\n",
    "print('atoms.pos[2] ->', atoms.pos[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The per-atom properties can also be converted into a flat pandas.DataFrame with the df() method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>atype</th>\n",
       "      <th>pos[0]</th>\n",
       "      <th>pos[1]</th>\n",
       "      <th>pos[2]</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.5</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   atype  pos[0]  pos[1]  pos[2]\n",
       "0      1     0.0     0.0     0.0\n",
       "1      1     0.5     0.5     0.0\n",
       "2      1     0.5     0.0     0.5\n",
       "3      1     0.0     0.5     0.5"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "atoms.df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3. System\n",
    "\n",
    "The System class gives a full representation of an atomic configuration by combining an atoms instance, a box instance, periodic boundary condition settings, and a list of element symbols. \n",
    "\n",
    "See the [1.3. System class Jupyter Notebook](1.3._System_class.html) for more detailed information and options."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.1. Create system\n",
    "\n",
    "A System is created by combining its components:\n",
    "\n",
    "- **atoms** is an Atoms object.\n",
    "\n",
    "- **box** is a Box object.\n",
    "\n",
    "- **pbc** is a list of three bools, where True indicates the box is periodic along the corresponding box vector.\n",
    "\n",
    "- **symbols** is a list of element model symbols for each unique atype value.\n",
    "\n",
    "- **scale** is a bool that indicates if atoms.pos are to be scaled relative to the box vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 4.050,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  4.050,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 4\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True False  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   0.000 |   0.000 |   0.000\n",
      "      1 |       1 |   2.025 |   2.025 |   0.000\n",
      "      2 |       1 |   2.025 |   0.000 |   2.025\n",
      "      3 |       1 |   0.000 |   2.025 |   2.025\n"
     ]
    }
   ],
   "source": [
    "system = am.System(atoms=atoms, box=box, pbc=[True, False, True], symbols='Al', scale=True)\n",
    "print(system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Load a System <a id='section3'></a>\n",
    "\n",
    "\n",
    "Systems can also be created by loading in atomic configurations from either\n",
    "\n",
    "- files of many different formats,\n",
    "- representations of configurations used by other Python packages, or\n",
    "- records stored in the potentials database.\n",
    "\n",
    "See the [1.4. Load and dump conversions Jupyter Notebook](1.4._Load_and_dump_conversions.html) for more detailed information on all the different available styles and options."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1. Load from POSCAR\n",
    "\n",
    "Create content in POSCAR format"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "fcc_poscar = \"\"\"POSCAR for fcc Al standard unit cell\n",
    "1.0\n",
    "4.05 0.00 0.00\n",
    "0.00 4.05 0.00\n",
    "0.00 0.00 4.05\n",
    "Al\n",
    "4 \n",
    "direct\n",
    "0.00 0.00 0.00\n",
    "0.50 0.50 0.00\n",
    "0.50 0.00 0.50\n",
    "0.00 0.50 0.50\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load content.  The load() function parameters are:\n",
    "\n",
    "- **style** (*str*) indicates the format of the content being loaded.\n",
    "\n",
    "- **content** (*any*) the content to be loaded.  For text formats, can be a str of the content, a file path or a file-like object.\n",
    "\n",
    "- **\\*\\*kwargs** (*any*) any extra style-specific keyword arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 4.050,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  4.050,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 4\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True  True  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   0.000 |   0.000 |   0.000\n",
      "      1 |       1 |   2.025 |   2.025 |   0.000\n",
      "      2 |       1 |   2.025 |   0.000 |   2.025\n",
      "      3 |       1 |   0.000 |   2.025 |   2.025\n"
     ]
    }
   ],
   "source": [
    "new_system = am.load('poscar', fcc_poscar)\n",
    "print(new_system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2. Load a database prototype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The potentials database stores structure information for many crystal prototypes, i.e. space group + wykoff sites without elemental information.  Crystals can easily be created from this by loading the prototype and specifying the element(s) and the necessary lattice constants."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "potdb = am.library.Database()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "database style local at C:\\Users\\lmh1\\Documents\\library\n"
     ]
    }
   ],
   "source": [
    "print(potdb.local_database)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 4.050,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  4.050,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 4\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True  True  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   0.000 |   0.000 |   0.000\n",
      "      1 |       1 |   0.000 |   2.025 |   2.025\n",
      "      2 |       1 |   2.025 |   0.000 |   2.025\n",
      "      3 |       1 |   2.025 |   2.025 |   0.000\n"
     ]
    }
   ],
   "source": [
    "new_system = am.load('prototype', name='A1--Cu--fcc', a=4.05, symbols='Al')\n",
    "print(new_system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3. Load a database  crystal\n",
    "\n",
    "The potentials database also contains relaxed crystal structures for the hosted interatomic potentials. If you know which potential you want to use, then you can load the appropriate relaxed structure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 4.050,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  4.050,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 4\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True  True  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   0.000 |   0.000 |   0.000\n",
      "      1 |       1 |   0.000 |   2.025 |   2.025\n",
      "      2 |       1 |   2.025 |   0.000 |   2.025\n",
      "      3 |       1 |   2.025 |   2.025 |   0.000\n"
     ]
    }
   ],
   "source": [
    "new_system = am.load('crystal', family='A1--Cu--fcc', potential_LAMMPS_id='2003--Zope-R-R--Al--LAMMPS--ipr1')\n",
    "print(new_system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. System Manipulations <a id='section4'></a>\n",
    "\n",
    "The System class was defined to make it easy for users to manipulate systems and atomic properties.  Additionally, there are a few System class methods that assist with some common manipulations.\n",
    "\n",
    "See the [1.3. System class Jupyter Notebook](1.3._System_class.html) for more detailed information and options."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1. System.rotate()\n",
    "\n",
    "The rotate() method transforms the system such that the new box vectors correspond to three integer [uvw] crystal vectors with respect to the current box vectors. This ensures that atomic compatibilities across all periodic boundaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [ 5.728,  0.000,  0.000]\n",
      "bvect =  [ 0.000,  5.728,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  4.050]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 8\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True  True  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   5.728 |   2.864 |   4.050\n",
      "      1 |       1 |   0.000 |   0.000 |   4.050\n",
      "      2 |       1 |   2.864 |   5.728 |   4.050\n",
      "      3 |       1 |   1.432 |   1.432 |   2.025\n",
      "      4 |       1 |   1.432 |   4.296 |   2.025\n",
      "      5 |       1 |   2.864 |   2.864 |   4.050\n",
      "      6 |       1 |   4.296 |   1.432 |   2.025\n",
      "      7 |       1 |   4.296 |   4.296 |   2.025\n"
     ]
    }
   ],
   "source": [
    "# Rotate system to crystal vectors [110], [-110], [001]\n",
    "uvws = [[ 1, 1, 0],\n",
    "        [-1, 1, 0], \n",
    "        [ 0, 0, 1]]\n",
    "system = system.rotate(uvws)\n",
    "\n",
    "# Show system is transformed and expanded\n",
    "print(system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2. System.supersize()\n",
    "\n",
    "A larger System (i.e. supercell) can be generated using the supersize() method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avect =  [11.455,  0.000,  0.000]\n",
      "bvect =  [ 0.000, 11.455,  0.000]\n",
      "cvect =  [ 0.000,  0.000,  8.100]\n",
      "origin = [ 0.000,  0.000,  0.000]\n",
      "natoms = 64\n",
      "natypes = 1\n",
      "symbols = ('Al',)\n",
      "pbc = [ True  True  True]\n",
      "per-atom properties = ['atype', 'pos']\n",
      "     id |   atype |  pos[0] |  pos[1] |  pos[2]\n",
      "      0 |       1 |   5.728 |   2.864 |   4.050\n",
      "      1 |       1 |   0.000 |   0.000 |   4.050\n",
      "      2 |       1 |   2.864 |   5.728 |   4.050\n",
      "      3 |       1 |   1.432 |   1.432 |   2.025\n",
      "      4 |       1 |   1.432 |   4.296 |   2.025\n",
      "      5 |       1 |   2.864 |   2.864 |   4.050\n",
      "      6 |       1 |   4.296 |   1.432 |   2.025\n",
      "      7 |       1 |   4.296 |   4.296 |   2.025\n",
      "      8 |       1 |  11.455 |   2.864 |   4.050\n",
      "      9 |       1 |   5.728 |   0.000 |   4.050\n",
      "     10 |       1 |   8.591 |   5.728 |   4.050\n",
      "     11 |       1 |   7.159 |   1.432 |   2.025\n",
      "     12 |       1 |   7.159 |   4.296 |   2.025\n",
      "     13 |       1 |   8.591 |   2.864 |   4.050\n",
      "     14 |       1 |  10.023 |   1.432 |   2.025\n",
      "     15 |       1 |  10.023 |   4.296 |   2.025\n",
      "     16 |       1 |   5.728 |   8.591 |   4.050\n",
      "     17 |       1 |   0.000 |   5.728 |   4.050\n",
      "     18 |       1 |   2.864 |  11.455 |   4.050\n",
      "     19 |       1 |   1.432 |   7.159 |   2.025\n",
      "     20 |       1 |   1.432 |  10.023 |   2.025\n",
      "     21 |       1 |   2.864 |   8.591 |   4.050\n",
      "     22 |       1 |   4.296 |   7.159 |   2.025\n",
      "     23 |       1 |   4.296 |  10.023 |   2.025\n",
      "     24 |       1 |  11.455 |   8.591 |   4.050\n",
      "     25 |       1 |   5.728 |   5.728 |   4.050\n",
      "     26 |       1 |   8.591 |  11.455 |   4.050\n",
      "     27 |       1 |   7.159 |   7.159 |   2.025\n",
      "     28 |       1 |   7.159 |  10.023 |   2.025\n",
      "     29 |       1 |   8.591 |   8.591 |   4.050\n",
      "     30 |       1 |  10.023 |   7.159 |   2.025\n",
      "     31 |       1 |  10.023 |  10.023 |   2.025\n",
      "     32 |       1 |   5.728 |   2.864 |   8.100\n",
      "     33 |       1 |   0.000 |   0.000 |   8.100\n",
      "     34 |       1 |   2.864 |   5.728 |   8.100\n",
      "     35 |       1 |   1.432 |   1.432 |   6.075\n",
      "     36 |       1 |   1.432 |   4.296 |   6.075\n",
      "     37 |       1 |   2.864 |   2.864 |   8.100\n",
      "     38 |       1 |   4.296 |   1.432 |   6.075\n",
      "     39 |       1 |   4.296 |   4.296 |   6.075\n",
      "     40 |       1 |  11.455 |   2.864 |   8.100\n",
      "     41 |       1 |   5.728 |   0.000 |   8.100\n",
      "     42 |       1 |   8.591 |   5.728 |   8.100\n",
      "     43 |       1 |   7.159 |   1.432 |   6.075\n",
      "     44 |       1 |   7.159 |   4.296 |   6.075\n",
      "     45 |       1 |   8.591 |   2.864 |   8.100\n",
      "     46 |       1 |  10.023 |   1.432 |   6.075\n",
      "     47 |       1 |  10.023 |   4.296 |   6.075\n",
      "     48 |       1 |   5.728 |   8.591 |   8.100\n",
      "     49 |       1 |   0.000 |   5.728 |   8.100\n",
      "     50 |       1 |   2.864 |  11.455 |   8.100\n",
      "     51 |       1 |   1.432 |   7.159 |   6.075\n",
      "     52 |       1 |   1.432 |  10.023 |   6.075\n",
      "     53 |       1 |   2.864 |   8.591 |   8.100\n",
      "     54 |       1 |   4.296 |   7.159 |   6.075\n",
      "     55 |       1 |   4.296 |  10.023 |   6.075\n",
      "     56 |       1 |  11.455 |   8.591 |   8.100\n",
      "     57 |       1 |   5.728 |   5.728 |   8.100\n",
      "     58 |       1 |   8.591 |  11.455 |   8.100\n",
      "     59 |       1 |   7.159 |   7.159 |   6.075\n",
      "     60 |       1 |   7.159 |  10.023 |   6.075\n",
      "     61 |       1 |   8.591 |   8.591 |   8.100\n",
      "     62 |       1 |  10.023 |   7.159 |   6.075\n",
      "     63 |       1 |  10.023 |  10.023 |   6.075\n"
     ]
    }
   ],
   "source": [
    "# Make system a 2x2x2 supercell of itself\n",
    "system = system.supersize(2, 2, 2)\n",
    "\n",
    "print(system)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3. Other Methods\n",
    "\n",
    "Other methods include:\n",
    "\n",
    "- **wrap()** wraps atoms around periodic boundaries and expands non-periodic boundaries to ensure all atom positions are within the box.\n",
    "\n",
    "- **normalize()** transforms the system such that box vectors and atomic positions are compatible with simulation codes, such as LAMMPS."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "  "
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
